package models

import (
	"fmt"
	"net/smtp"
	"net/textproto"
	"strconv"

	"errors"

	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/jordan-wright/email"
)

// 检查用户是否已经注册
// 若用户已经注册，error返回nil
// 返回参数：
// 0：用户已经注册
// 1：用户尚未注册
func CheckUsr(uname string) (*User, int8) {
	var ORM = orm.NewOrm()
	qs := ORM.QueryTable("user")
	user := new(User)
	err := qs.Filter("name", uname).One(user)
	if err != nil {
		return nil, 1
	}
	return user, 0
}

// 注册用户
// 参数说明：
// 0：用户注册成功
// 1：用户注册失败，用户已经注册，用户名已经存在
// 2：用户注册失败，密码不合规定，密码不得小于八位
// 3：用户注册失败，年龄格式错误
// 4：用户注册失败，年龄不符合规定
// 5：用户注册失败，性别格式错误/性别类型不符合规定
// 6：用户注册失败，系统故障
// 7：用户注册失败，发送邮件失败
// 8:用户注册失败,邮箱已经占用
func Registered(uname, password, age, sex, phone, email, idCard string) int8 {
	// 检查用户是否已经注册
	_, status := CheckUsr(uname)
	if status == 0 {
		return 1
	}

	if !Checkemail(email) {
		return 8
	}

	if len(password) < 8 {
		return 2
	}

	// var Tage time.Time
	var Isex64 int64
	beego.Error(age)
	Tage, err := String2Time(age)
	if err != nil {
		return 3
	}
	datenow := time.Now()
	if datenow.Year()-Tage.Year() <= 18 ||
		(datenow.Year()-Tage.Year() == 18 && datenow.Month() >= Tage.Month()) {
		//年龄小于18岁
		return 4
	}
	beego.Error(Tage)
	// beego.Error(err)
	Isex64, err = strconv.ParseInt(sex, 10, 64)
	if err != nil {
		return 5
	}

	//判断int64能否被转化为int8
	if int64(int8(Isex64)) != Isex64 {
		return 5
	}
	Isex8 := int8(Isex64)

	// Isex, err = String2Int(sex, 32)
	user := &User{
		Name:     uname,
		Password: PasswordMD5(password),
		Age:      Tage,
		Sex:      Isex8,
		Phone:    phone,
		Email:    email,
		Idcard:   idCard,
	}
	enumber := GetRandomString(14)
	// 发送激活邮件给用户
	status = SendEmail(email, "marx航空 <marx_fly@163.com>", "请激活您的账号", Gethtml(uname, email, enumber))
	if status == 1 {
		return 7
	}

	o := orm.NewOrm()
	_, err = o.Insert(user)

	if err != nil {
		return 6
	}

	// 插入激活信息
	status = Insertact(PasswordMD5(email), enumber)
	if status == 1 {
		return 6
	}

	return 0
}

// 登录操作
// 状态码表示如下
// 0：表示登陆成功
// 1：表示登录失败，密码错误
// 2：表示登录失败，用户不存在
// 3：登录失败，其他情况
func Login(name, password string) (int8, error) {
	// 使用md5加密
	pwd := PasswordMD5(password)
	o := orm.NewOrm()
	qs := o.QueryTable("user")
	user := new(User)
	err := qs.Filter("name", name).One(user)
	if err != nil {
		if user.Name == "" {
			return 2, errors.New("找不此用户")
		}
		return 3, err
	}

	if user.Password == pwd {
		if user.Activate == true {
			return 0, nil
		} else {
			return 4, errors.New("尚未激活")
		}
	} else {
		beego.Error("密码错误" + user.Password + " " + pwd)
		return 1, errors.New("密码错误")
	}
}

// 0：查询信息成功
// 1：用户不存在
// 2：查询失败，系统错误
func Listmess(name string) ([]*Usermessage, int8) {
	o := orm.NewOrm()
	Sendmess(o)
	qs := o.QueryTable("usermessage")
	userid, status := Getuserid(name)
	if status != 0 {
		beego.Error()
		return nil, 1
	}
	umess := make([]*Usermessage, 0)
	// 将最新的信息置顶
	_, err := qs.OrderBy("-created").Filter("userid", userid).All(&umess)
	if err != nil {
		return nil, 2
	}
	return umess, 0
}

// 1：用户不存在
// 2：messid参数错误
// 3：查找的用户信息不存在
// 4：删除出错
// 5：没有权限
func Deletemess(name, messid string) int8 {
	o := orm.NewOrm()
	qs := o.QueryTable("usermessage")
	userid, status := Getuserid(name)
	if status != 0 {
		beego.Error()
		return 1
	}
	mid, err := strconv.ParseInt(messid, 10, 64)
	if err != nil {
		return 2
	}
	mess := new(Usermessage)
	err = qs.Filter("id", mid).One(mess)
	if err != nil {
		return 3
	}

	if userid == mess.Userid {
		_, err = o.Delete(mess)
		if err != nil {
			return 4
		}
		return 0
	} else {
		return 5
	}
}

// 参数说明
// address：邮箱地址
// from：备注
// title：标题名
// html：内容(html格式)
func SendEmail(address, from, title, html string) int8 {
	e := &email.Email{
		To:      []string{address},
		From:    from,
		Subject: title,
		Text:    []byte("Text Body is, of course, supported!"),
		HTML:    []byte(html),
		Headers: textproto.MIMEHeader{},
	}
	p := email.NewPool(
		"smtp.163.com:25",
		4,
		smtp.PlainAuth("", "marx_fly@163.com", "chen1995", "smtp.163.com"),
	)
	err := p.Send(e, 10*time.Second)
	if err != nil {
		fmt.Println(err.Error())
		return 1
	}
	return 0
}

// 激活账号：
// 查询Usr表是否存在该账号
// 检查Email表是否存在激活记录
// 存在则标志user表激活
// 删除Email表信息
// 返回参数：
// 0：激活成功
// 1：激活失败，用户不存在
// 2：激活失败，用户已经激活
// 3：激活失败，没有找到激活信息
func Activate(name, email, number string) int8 {
	o := orm.NewOrm()
	user, status := CheckUsr(name)
	if status != 0 {
		//用户不存在
		return 1
	}
	if user.Activate == true {
		return 2
	}
	emails := PasswordMD5(email)
	e, status1 := Getemail(emails, number)
	if status1 != 0 {
		return 3
	}
	user.Activate = true
	o.Update(user)
	o.Delete(e)
	return 0
}

// 状态值信息：
// 0：正常，有等待激活信息
// 1：错误，无等待激活信息
func Getemail(email, number string) (*Email, int8) {
	o := orm.NewOrm()
	qs := o.QueryTable("email")
	e := new(Email)
	err := qs.Filter("email", email).Filter("number", number).One(e)
	if err != nil {
		return nil, 1
	}
	return e, 0
}

// 删除Email的待激活信息
func Deleteacti(id int64) int8 {
	o := orm.NewOrm()
	e := Email{Id: id}
	_, err := o.Delete(e)
	if err != nil {
		return 1
	}
	return 0
}

var HTML = "hh"

// 插入激活信息
func Insertact(email, number string) int8 {
	e := &Email{
		Email:  email,
		Number: number,
	}
	o := orm.NewOrm()
	o.Insert(e)

	return 0
}

// <link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">

// 获取对应的html文本
func Gethtml(name, email, number string) string {
	input1 := "name=" + name
	input2 := "email=" + email
	input3 := "number=" + number
	attributes := input1 + "&" + input2 + "&" + input3

	before := "<body><style type=\"text/css\">@import url(https://fonts.googleapis.com/css?family=Oswald);body{background-color:#eee;font-family:'Oswald',sans-serif;margin:0;padding:0;}#page{background-color:#fff;width:320px;height:auto;margin:10px auto;}h2{color:#5a514c;background-color:#fdd;font-size:24px;text-align:center;text-transform: uppercase;letter-spacing:.3em;margin:0 0 23px 0;}div.info{padding:0 60px 30px 60px;}p{color:#5a514c;padding:10px;margin:20px auto;min-width:20%;max-width:80%;border-radius:5px;text-align:center;}</style><div id=\"page\"><h2>Thank you for<br/>registration</h2><div class=\"info\"><p>Your registration code is <a href=\"#\">"
	before = before + number

	after := "</a>.</p><p><a href=\"http://localhost:8080/login/activate?"
	after = after + attributes
	after = after + "\">Click here</a> to verify your e-mail.</p></div></div></body>"
	html := before + after
	return html
}

// 返回用户的机票信息
func Getticket(name string) ([]*Order, int8) {
	o := orm.NewOrm()
	qs := o.QueryTable("order")
	orders := make([]*Order, 0)
	uid, status := Getuserid(name)
	if status != 0 {
		return nil, 1
	}
	_, err := qs.Filter("userid", uid).Filter("cancel", false).All(&orders)
	if err != nil {
		return nil, 2
	}
	return orders, 0
}

// 获取航班的座位信息
func Getseatmess(name string, alineid int64) (*Seat, int8) {
	o := orm.NewOrm()
	qs := o.QueryTable("seat")
	seat := new(Seat)
	uid, status := Getuserid(name)
	if status != 0 {
		return nil, 1
	}
	err := qs.Filter("userid", uid).Filter("Alineid", alineid).One(seat)
	if err != nil {
		return nil, 2
	}
	return seat, 0
}
